package com.ruoyi.system.service.impl;

import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import cn.hutool.extra.qrcode.QrCodeUtil;
import com.ruoyi.common.enums.SaleOrPurchType;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.DictUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.bean.BeanUtils;
import com.ruoyi.common.utils.numGene.NumberGene;
import com.ruoyi.common.utils.uuid.UUID;
import com.ruoyi.system.domain.*;
import com.ruoyi.system.service.*;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.system.mapper.WaybillsMapper;

import javax.imageio.ImageIO;

/**
 * 运单Service业务层处理
 * 
 * @author he
 * @date 2025-08-18
 */
@Service
public class WaybillsServiceImpl implements IWaybillsService 
{
    @Autowired
    private WaybillsMapper waybillsMapper;

    @Autowired
    private ISalePlanService iSalePlanService;

    @Autowired
    private IDriversService driversService;

    @Autowired
    private ICarsService icarsService;

    @Autowired
    private IInventorysService iInventorysService;

    @Autowired
    private IInventoryAdjustLogService iInventoryAdjustLogService;


    @Autowired
    private IFundsService iFundsService;

    @Autowired
    private IAccountDetailssService iAccountDetailssService;


    /**
     * 查询运单
     * 
     * @param id 运单主键
     * @return 运单
     */
    @Override
    public Waybills selectWaybillsById(Long id)
    {
        Waybills waybills = waybillsMapper.selectWaybillsById(id);
        //处理goodssList
        List<WaybillDetails> goodsList = new ArrayList<>();
        WaybillDetails waybillDetails = new WaybillDetails();
        BeanUtils.copyProperties(waybills,waybillDetails);
        goodsList.add(waybillDetails);
        waybills.setGoodsList(goodsList);

        return waybills;
    }

    /**
     * 查询运单列表
     * 
     * @param waybills 运单
     * @return 运单
     */
    @Override
    public List<Waybills> selectWaybillsList(Waybills waybills)
    {
        return waybillsMapper.selectWaybillsList(waybills);
    }

    /**
     * 新增运单
     * 
     * @param waybills 运单
     * @return 结果
     */
    @Override
    public int insertWaybills(Waybills waybills)
    {
        waybills.setCreateTime(DateUtils.getNowDate());
        waybills.setCreateUserId(SecurityUtils.getUserId());
        waybills.setCreateUserName(SecurityUtils.getUsername());

        //生成编号 和取货码
        if (Long.valueOf(SaleOrPurchType.SALE.getCode()).equals(waybills.getType())) {
            waybills.setNumber(NumberGene.generateCode("SSYD"));
        } else {
            waybills.setNumber(NumberGene.generateCode("CGYD"));
        }
        waybills.setDispatchtime(DateUtils.dateTimeNow("yyyy-MM-dd HH:mm:ss"));

        return waybillsMapper.insertWaybills(waybills);
    }

    /**
     * 修改运单
     * 
     * @param waybills 运单
     * @return 结果
     */
    @Override
    public int updateWaybills(Waybills waybills)
    {
        waybills.setUpdateTime(DateUtils.getNowDate());
    waybills.setUpdateUserId(SecurityUtils.getUserId());
    waybills.setUpdateUserName(SecurityUtils.getUsername());
        return waybillsMapper.updateWaybills(waybills);
    }

    /**
     * 批量删除运单
     * 
     * @param ids 需要删除的运单主键
     * @return 结果
     */
    @Override
    public int deleteWaybillsByIds(Long[] ids)
    {
        return waybillsMapper.deleteWaybillsByIds(ids);
    }

    /**
     * 删除运单信息
     * 
     * @param id 运单主键
     * @return 结果
     */
    @Override
    public int deleteWaybillsById(Long id)
    {
        return waybillsMapper.deleteWaybillsById(id);
    }

    @Override
    public int signStateChange(List<Long> ids) {
        return waybillsMapper.signStateChange(ids);
    }

    @Override
    public Waybills book(Appointment appointment) {

        //查找是否已存在预约数据,未完成
//        int count = waybillsMapper.selectWaybillsByCode(appointment.getCode());


        //查找计划
        List<SalePlan> salePlan = iSalePlanService.selectSalePlanByCode(appointment.getCode());

        Phone phone = driversService.driverInfoPhone(appointment.getFwid());

        //生成运单
        if (CollectionUtils.isNotEmpty(salePlan)){
            SalePlan salePlan1 = salePlan.get(0);

            Waybills waybills = new Waybills();

            waybills.setCreateTime(DateUtils.getNowDate());
//            waybills.setCreateUserId(SecurityUtils.getUserId());
//            waybills.setCreateUserName(SecurityUtils.getUsername());

            waybills.setPickCode(appointment.getCode());
            waybills.setItemName(salePlan1.getItemName());
            waybills.setPlanName(salePlan1.getName());
            waybills.setItemId(salePlan1.getItemId());
            waybills.setItemModel(salePlan1.getItemModel());
            waybills.setItemPrice(salePlan1.getItemPrice());
            waybills.setReceiveCompany(salePlan1.getReceiveCompany());
            waybills.setReceiveCompanyId(salePlan1.getReceiveCompanyId());
            waybills.setSendoutCompany(salePlan1.getSendoutCompany());
            waybills.setSendoutCompanyId(salePlan1.getSendoutCompanyId());
            waybills.setLicensePlate(phone.getLicensePlate());
            waybills.setDriverId(Long.valueOf(1));
            waybills.setDriverName(phone.getName());
            waybills.setDriverIdCard(phone.getIdCard());
            waybills.setFwid(appointment.getFwid());
            waybills.setType(salePlan1.getType());

            //生成编号 和取货码
            if (Long.valueOf(SaleOrPurchType.SALE.getCode()).equals(salePlan1.getType())) {
                waybills.setNumber(NumberGene.generateCode("SSYD"));
                waybills.setTypeName("销售");
            } else {
                waybills.setNumber(NumberGene.generateCode("CGYD"));
                waybills.setTypeName("采购");
            }
            waybills.setDispatchtime(DateUtils.dateTimeNow("yyyy-MM-dd HH:mm:ss"));


            //二维码UUID
            waybills.setSqare02(UUID.randomUUID().toString());

            //生成二维码图片信息
            BufferedImage bufferedImage = QrCodeUtil.generate(waybills.getNumber(), 300, 300);
            // 将 BufferedImage 转换为 Base64 字符串
            try {
                String base64Image = encodeToString(bufferedImage, "png");
                waybills.setSqare03(base64Image);
            } catch (Exception e){
                e.printStackTrace();
            }

            return waybills;


        }
        return new Waybills();
    }

    public static String encodeToString(BufferedImage image, String type) throws IOException {
        // 创建一个 ByteArrayOutputStream 来存储图像数据
        ByteArrayOutputStream baos = new ByteArrayOutputStream();

        // 将 BufferedImage 写入 ByteArrayOutputStream，指定图像格式
        ImageIO.write(image, type, baos);

        // 获取图像的字节数组
        byte[] imageBytes = baos.toByteArray();

        // 使用 Base64 编码器将字节数组转换为 Base64 字符串
        String base64String = Base64.getEncoder().encodeToString(imageBytes);

        // 关闭 ByteArrayOutputStream
        baos.close();

        return base64String;
    }

    @Override
    public Waybills selectWaybillsByCode(String code) {
        //查找运单
        Waybills waybills = new Waybills();
        waybills.setFwid(code);
//        Phone phone = driversService.driverInfoPhone();
//        waybills.setLicensePlate(phone.getLicensePlate());

        Waybills waybillsNew = waybillsMapper.selectWaybillsByCode(waybills);

        return waybillsNew;

    }



    @Override
    public List<Waybills> selectWaybillsComplate(Waybills waybills) {
        List<Waybills> waybillsList = waybillsMapper.selectWaybillsComplate(waybills);
        return waybillsList;
    }

    @Override
    public int rebackState(Waybills waybills) {

        Long yyskState = waybills.getYyskState();
        Long id = waybills.getId();

        waybillsMapper.rebackState(id,yyskState);

        return 1;

    }

    @Override
    public int bookConfirm(Waybills waybills) {
        //查找是否存在已预约但未完成的订单
        Waybills waybillsSel = new Waybills();
        waybillsSel.setLicensePlate(waybills.getLicensePlate());
        waybillsSel.setWaybillState(Long.valueOf(1));
        List<Waybills> waybillsList = waybillsMapper.selectWaybillsList(waybillsSel);
        if (CollectionUtils.isNotEmpty(waybillsList)){
            return 2;
        } else {

            return waybillsMapper.insertWaybills(waybills);
        }
    }

    @Override
    public int register(Appointment appointment) {

        //判断个数 存在更新 不存在新增
        Drivers driversSel = new Drivers();
        driversSel.setSqare01(appointment.getFwid());
        List<Drivers> drivers1 = driversService.selectDriversList(driversSel);

        Drivers drivers = new Drivers();
        drivers.setName(appointment.getRealName());
        drivers.setIdCard(appointment.getIdCard());
        drivers.setTelephone(appointment.getPhone());
        drivers.setSqare01(appointment.getFwid());

        if (CollectionUtils.isNotEmpty(drivers1) && drivers1.size() > 0){
            drivers.setId(drivers1.get(0).getId());
            driversService.updateDrivers(drivers);
        } else {
            driversService.insertDrivers(drivers);
        }

        Cars carsSel = new Cars();
        carsSel.setSqare01(appointment.getFwid());
        List<Cars> cars1 = icarsService.selectCarsList(carsSel);
        Cars cars = new Cars();
        cars.setSqare01(appointment.getFwid());
        cars.setLicensePlate(appointment.getLicensePlate());
        cars.setDriverId(drivers.getId());
        if (CollectionUtils.isNotEmpty(cars1) && cars1.size() > 0){
            cars.setId(cars1.get(0).getId());
            icarsService.updateCars(cars);
        } else {
            icarsService.insertCars(cars);
        }

        return 1;

    }

    @Override
    public Appointment getRegisterInfo(Appointment appointment) {
        //判断个数 存在更新 不存在新增
        Drivers driversSel = new Drivers();
        driversSel.setSqare01(appointment.getFwid());
        List<Drivers> drivers1 = driversService.selectDriversList(driversSel);

        Cars carsSel = new Cars();
        carsSel.setSqare01(appointment.getFwid());
        List<Cars> cars1 = icarsService.selectCarsList(carsSel);


        if (CollectionUtils.isNotEmpty(drivers1) && CollectionUtils.isNotEmpty(cars1)){
            Appointment appointmentSel = new Appointment();
            appointmentSel.setIdCard(drivers1.get(0).getIdCard());
            appointmentSel.setLicensePlate(cars1.get(0).getLicensePlate());
            appointmentSel.setPhone(drivers1.get(0).getTelephone());
            appointmentSel.setRealName(drivers1.get(0).getName());
            appointmentSel.setFwid(drivers1.get(0).getSqare01());
            return appointmentSel;
        }

        return null;

    }

    @Override
    public void updateWaybillsToPlan() {

        Waybills waybills = new Waybills();
        String dictValue = DictUtils.getDictValue("waybill_state", "已完成");
        waybills.setWaybillState(Long.valueOf(dictValue));
        waybills.setCheckUp(Long.valueOf(1));

        //查找当前已完成数据
        List<Waybills> waybillsList = waybillsMapper.selectWaybillsComplate(waybills);

        if (CollectionUtils.isNotEmpty(waybillsList)) {
            Map<Long, List<Waybills>> collect2 = waybillsList.stream().collect(Collectors.groupingBy(Waybills::getPlanId));

            Set<Long> longs = collect2.keySet();
            List<Long> collect = new ArrayList<>(longs);
            //查找计划
            List<SalePlan> salePlanList = iSalePlanService.selectSalePlanListByIdList(collect);

            Map<Long, SalePlan> collect3 = salePlanList.stream()
                    .collect(Collectors.toMap(SalePlan::getId, salePlan -> salePlan));

            collect2.forEach((key,value)->{
                SalePlan salePlans = collect3.get(key);

                //车数
                int size = value.size();
                //运单拉量
                BigDecimal totalJ = value.stream()
                        .map(Waybills::getJ)  // 获取每个 Waybills 对象的 j 字段
                        .filter(Objects::nonNull)  // 过滤掉 null 值
                        .reduce(BigDecimal.ZERO, BigDecimal::add);  // 求和

                //总数
                BigDecimal total = salePlans.getTotal();
                BigDecimal completed1 = salePlans.getCompleted();
                BigDecimal remain = salePlans.getRemain();


                //剩余量
                BigDecimal re = remain.subtract(totalJ);
                BigDecimal com = completed1.add(totalJ);

                //完成率
                BigDecimal divide = com.divide(total,2, RoundingMode.HALF_UP).multiply(new BigDecimal(100));
                //扣减对应的计划量
                salePlans.setRemain(re);
                salePlans.setCompleted(com);
                salePlans.setCompletionRate(divide);
                salePlans.setWaybillQty(salePlans.getWaybillQty() + size);

                //计划状态
                String dictValue1 = DictUtils.getDictValue("plan_state", "执行中");
                salePlans.setPlanState(Long.valueOf(dictValue1));

                //扣减对应的库存量
                iSalePlanService.updateSalePlan(salePlans);

            });

            List<Long> collect1 = waybillsList.stream().map(Waybills::getId).collect(Collectors.toList());
            //回填已扣减状态
            waybillsMapper.updateWaybillsHandleState(collect1);

        }


        updateWaybillsToInventory(waybillsList);


    }

    @Override
    public void updateWaybillsToInventory(List<Waybills> waybillsList) {



        if (CollectionUtils.isNotEmpty(waybillsList)){
//            Map<Long, List<Waybills>> collect = waybillsList.stream().collect(Collectors.groupingBy(Waybills::getStockId));
            //过滤运单没有仓库和物料id的
            List<Waybills> collect2 = waybillsList.stream().filter(item -> ObjectUtils.isNotEmpty(item.getStockId()) && ObjectUtils.isNotEmpty(item.getItemId())
            ).collect(Collectors.toList());

            List<Long> collectIds = waybillsList.stream().filter(item -> ObjectUtils.isEmpty(item.getStockId()) || ObjectUtils.isEmpty(item.getItemId())
            ).map(Waybills::getId).collect(Collectors.toList());

            if (CollectionUtils.isNotEmpty(collectIds)){

                waybillsMapper.updateWaybillsCheckUpBatch(collectIds,3,"仓库ID或货物ID为空");
            }


            if (CollectionUtils.isNotEmpty(collect2)) {
                Map<Map.Entry<Long, Long>, List<Waybills>> collectNew = collect2.stream()
                        .collect(Collectors.groupingBy(w -> new AbstractMap.SimpleEntry<>(w.getStockId(), w.getItemId())));

                collectNew.forEach((key, value) -> {

                    Map.Entry<Long, Long> key1 = key;
                    Long stockId = key1.getKey();
                    Long itemId = key1.getValue();

                    Inventorys inventorysNew = new Inventorys();
                    inventorysNew.setStockId(stockId);
                    inventorysNew.setGoodsId(itemId);

                    //查找库存
                    List<Inventorys> inventoryList = iInventorysService.selectInventorysList(inventorysNew);
                    if (CollectionUtils.isEmpty(inventoryList)) {
                        return;
                    }
                    Inventorys inventorys = inventoryList.get(0);
                    List<Waybills> collect1 = value.stream().sorted(Comparator.comparing(Waybills::getCreateTime)).collect(Collectors.toList());

                    List<InventoryAdjustLog> inventoryAdjustLogList = new ArrayList<>();

                    BigDecimal goodsCount = inventorys.getGoodsCount();
                    BigDecimal subtract = new BigDecimal(0);
                    List<Waybills> waybillsListUpd = new ArrayList<>();
                    for (Waybills waybills1 : collect1) {
                        InventoryAdjustLog inventoryAdjustLog = new InventoryAdjustLog();
                        inventoryAdjustLog.setStockId(waybills1.getStockId());
                        inventoryAdjustLog.setGoodsId(waybills1.getItemId());
                        inventoryAdjustLog.setStockName(waybills1.getStockName());
                        inventoryAdjustLog.setGoodsName(waybills1.getItemName());
                        inventoryAdjustLog.setNumber(waybills1.getNumber());
                        inventoryAdjustLog.setGoodsModel(waybills1.getItemModel());
                        inventoryAdjustLog.setInventoryId(inventorys.getId());
                        //判断  销售 -
                        if (Long.valueOf(SaleOrPurchType.SALE.getCode()).equals(waybills1.getType())) {
                            BigDecimal j = waybills1.getJ();
                            subtract = goodsCount.subtract(j);

                            inventoryAdjustLog.setBeforeQuantity(goodsCount);
                            goodsCount = subtract;
                            inventoryAdjustLog.setAfterQuantity(subtract);
                            inventoryAdjustLog.setIncrease(j.negate());
                            inventoryAdjustLog.setSources("销售运单");
                            inventoryAdjustLogList.add(inventoryAdjustLog);
                            waybillsListUpd.add(waybills1);

                        } else if (Long.valueOf(SaleOrPurchType.PURCH.getCode()).equals(waybills1.getType())) {
                            //采购 +
                            BigDecimal j = waybills1.getJ();
                            subtract = goodsCount.add(j);
                            //生成库存日志
                            inventoryAdjustLog.setBeforeQuantity(goodsCount);
                            goodsCount = subtract;
                            inventoryAdjustLog.setAfterQuantity(subtract);
                            inventoryAdjustLog.setIncrease(j);
                            inventoryAdjustLog.setSources("采购运单");
                            inventoryAdjustLogList.add(inventoryAdjustLog);
                            waybillsListUpd.add(waybills1);

                        }


                    }

                    //库存日志
                    if (CollectionUtils.isNotEmpty(inventoryAdjustLogList)) {
                        iInventoryAdjustLogService.insertInventoryAdjustLogList(inventoryAdjustLogList);
                    }
                    //更新库存
                    Inventorys inventorysUpd = new Inventorys();
                    inventorysUpd.setId(inventorys.getId());
                    inventorysUpd.setGoodsCount(goodsCount);
                    iInventorysService.updateInventorys(inventorysUpd);
                    //更新运单状态为 已核对
                    if (CollectionUtils.isNotEmpty(waybillsListUpd)) {
                        List<Long> collect = waybillsListUpd.stream().map(Waybills::getId).collect(Collectors.toList());
                        waybillsMapper.updateWaybillsCheckUpBatch(collect,2,"");
                    }
                });

            }

        }

    }


    public void updateWaybillsToFunds(List<Waybills> waybillsList) {



        if (CollectionUtils.isNotEmpty(waybillsList)){
//            Map<Long, List<Waybills>> collect = waybillsList.stream().collect(Collectors.groupingBy(Waybills::getStockId));
            //过滤运单 销售的  客户不为空
            List<Waybills> collect2 = waybillsList.stream().filter(item -> item.getType() == SaleOrPurchType.SALE.getCode().longValue() && ObjectUtils.isNotEmpty(item.getReceiveCompanyId())
            ).collect(Collectors.toList());

            List<Long> collectIds = waybillsList.stream().filter(item -> item.getType() == SaleOrPurchType.SALE.getCode().longValue() && ObjectUtils.isEmpty(item.getReceiveCompanyId())
            ).map(Waybills::getId).collect(Collectors.toList());

            if (CollectionUtils.isNotEmpty(collectIds)){

                waybillsMapper.updateWaybillsCheckUpBatch(collectIds,3,"客户ID为空");
            }


            if (CollectionUtils.isNotEmpty(collect2)) {
                Map<Long, List<Waybills>> collectNew = collect2.stream()
                        .collect(Collectors.groupingBy(w -> w.getReceiveCompanyId()));

                collectNew.forEach((key, value) -> {

                    Long receiveCompanyId = key;

                    Funds funds = new Funds();
                    funds.setCustomerId(receiveCompanyId);

                    //查找账户金额
                    Funds funds1 = iFundsService.selectFundsById(receiveCompanyId);

                    if (ObjectUtils.isEmpty(funds1)) {
                        return;
                    }

                    List<Waybills> collect1 = value.stream().sorted(Comparator.comparing(Waybills::getCreateTime)).collect(Collectors.toList());

                    List<AccountDetailss> accountDetailsses = new ArrayList<>();

                    BigDecimal residueAmount = funds1.getResidueAmount();
                    BigDecimal subtract = residueAmount;
                    BigDecimal dedution = new BigDecimal(0);
                    List<Waybills> waybillsListUpd = new ArrayList<>();
                    for (Waybills waybills1 : collect1) {

                        //账户详情
                        AccountDetailss accountDetailss = new AccountDetailss();
                        accountDetailss.setAmountId(funds.getId());
                        accountDetailss.setTransactionNumber(NumberGene.generateCode("KK"));
                        accountDetailss.setTransactionAmountBefore(funds.getResidueAmount());
                        accountDetailss.setTransactionAmount(waybills1.getSettlementAmount());
                        accountDetailss.setTransactionType(SaleOrPurchType.DEDUTION_TYPE.getMessage());
                        accountDetailss.setResidueAmount(subtract.subtract(waybills1.getSettlementAmount()));
                        accountDetailss.setAmountName(funds.getName());
                        subtract = accountDetailss.getResidueAmount();
                        dedution.add(waybills1.getSettlementAmount());

                        accountDetailsses.add(accountDetailss);
                    }

                    //账户日志
                    if (CollectionUtils.isNotEmpty(accountDetailsses)) {
                        iAccountDetailssService.insertAccountDetailssList(accountDetailsses);
                    }
                    //更新账户
                    Funds funds2 = new Funds();
                    funds2.setId(funds1.getId());
                    funds2.setResidueAmount(funds1.getResidueAmount().subtract(dedution));
                    funds2.setTotalDeduction(funds1.getTotalDeduction().add(dedution));
                    iFundsService.updateFunds(funds2);
                    //更新运单状态为 已核对
                    if (CollectionUtils.isNotEmpty(waybillsListUpd)) {
                        List<Long> collect = waybillsListUpd.stream().map(Waybills::getId).collect(Collectors.toList());
                        waybillsMapper.updateWaybillsCheckUpBatch(collect,2,"");
                    }
                });

            }

        }

    }

    @Override
    public void updateWaybillsCheckUp(Waybills waybills) {
        waybillsMapper.updateWaybillsCheckUp(waybills);
    }

    @Override
    public int updateApprovalState(List<Long> ids, Integer approvalState) {
        return waybillsMapper.updateApprovalState(ids, approvalState);
    }
}
